#include "transfile.h"

int putsFile(int peerfd, char *para)
{
	int cmd = CMD_TYPE_PUT;
	// 1. 读取本地文件
	int fd = open(para, O_RDWR);
	ERROR_CHECK(fd, -1, "open");

	// 2. 先发文件名
	sendMsg(peerfd, para);
	int flag = 0;
	recv(peerfd, &flag, 4, MSG_WAITALL);

	//发送md5值
	char md5[33] = {0};
	memset(&md5,0,33);
	getmd5(para, md5);
	printf("md5 = %s\n",md5);
	send(peerfd, &cmd, 4, MSG_WAITALL);
	sendMsg(peerfd, md5);
	recv(peerfd, &flag, 4, MSG_WAITALL);

	// 3. 再发文件内容
	// 3.1 获取文件的长度
	struct stat st;
	fstat(fd, &st);
	printf("file's length: %ld\n", st.st_size);
	char filelength[200] = {0};
	sprintf(filelength, "%ld", st.st_size);
	printf("filelength = %s\n", filelength);
	send(peerfd, &cmd, 4, MSG_WAITALL);
	sendMsg(peerfd, filelength);

	printf("文件长度发送完成\n");
	// 3.2收服务器端文件长度
	size_t sendSize = 0;
	recvCircle(peerfd, (char *)&sendSize, 8);
	if (sendSize == st.st_size)
	{
		printf("文件传输完毕\n");
		return 0;
	}

	printf("开始传送文件\n");
	// 3.3断点续传
	lseek(fd, sendSize, SEEK_SET);
	train_t train;
	int spipe[2];
	pipe(spipe);
	while (sendSize < st.st_size)
	{
		send(peerfd, &cmd, 4, MSG_WAITALL);
		int len = splice(fd,NULL,spipe[1],NULL,1024,SPLICE_F_MORE);
		send(peerfd,&len,4,MSG_WAITALL);
		splice(spipe[0],NULL,peerfd,NULL,len,SPLICE_F_MORE);
		sendSize += len;
		recv(peerfd, &flag, 4, MSG_WAITALL);
	}
	close(fd);
	return sendSize - st.st_size;
}

int getsFile(int peerfd, char *para)
{
	// 1. 先发md5值。
	train_t train;
	memset(&train, 0, sizeof(train));
	train.length = strlen(para);
	strcpy(train.buff, para);
	int ret = send(peerfd, &train, 4 + train.length, MSG_WAITALL); // 104

	//判断文件是否存在
	int flag = 200;
	recv(peerfd,&flag,4,MSG_WAITALL);
	if(flag == 404)
	{
		printf("文件不存在\n");
		return -1;
	}
	// 2.在本地建立文件
	int fd = open(para, O_RDWR | O_CREAT | O_TRUNC, 0664);
	ERROR_CHECK(fd, -1, "open");

	// 3. 再接收文件内容
	// 3.1 先接文件长度
	size_t filelength = 0;

	recvCircle(peerfd, (char *)&filelength, 8);
	printf("filecontent length: %ld\n", filelength);

	// 3.2 再接文件内容
	int length = 0;
	size_t recvSize = 0;
	int spipe[2];
	pipe(spipe);
	while (recvSize < filelength)
	{
		length = splice(peerfd,NULL,spipe[1],NULL,4096,SPLICE_F_MORE);
		splice(spipe[0],NULL,fd,NULL,length,SPLICE_F_MORE);
		recvSize += length;
	}
	close(fd);
	return recvSize - filelength;
}

int recvCircle(int fd, char *buff, int length)
{
	char *pbuf = buff;
	int left = length;
	int ret = 0;
	while (left > 0)
	{
		ret = recv(fd, pbuf, left, 0);
		if (0 == ret)
		{
			close(fd);
			break;
		}
		else if (ret == -1 && errno == EINTR)
		{
			continue;
		}
		else if (ret == -1)
		{
			perror("recv");
			break;
		}
		else
		{ // > 0
			pbuf += ret;
			left -= ret;
		}
		// printf("recv %f%%\r",(float)ret/left * 100);
	}
	return length - left;
}